package com.vf.cloud.server.signalling.server;

import java.util.TimerTask;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.jfinal.kit.StrKit;
import com.vf.cloud.common.constant.Cache;
import com.vf.cloud.server.signalling.SignallingServer;
import com.vf.cloud.server.signalling.channel.SignallingChannelInitializer;
import com.vf.cloud.server.signalling.pool.CachePool;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.WriteBufferWaterMark;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Server implements Runnable {

	private EventLoopGroup boss;
	private EventLoopGroup work;
	private ExecutorService executor;
	private Channel channel;
	
	/**
	 * 0-停止
	 * 1-正在启动
	 * 2-运行中
	 * 3-停止中
	 * 
	 */
	private int status=0;

	public void run() {
		executor = Executors.newFixedThreadPool(1);
		try {
			executor.submit(new Callable<String>() {
				@Override
				public String call() throws Exception {
					start();
					return "";
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void start() {
		try {
			
			status=1;
			ServerBootstrap bootstrap = new ServerBootstrap();
			boss = new NioEventLoopGroup();
			work = new NioEventLoopGroup();

			log.info(">>>正在启动SignallingServer:" + Cache.signalling.getSignalingInnerIP());
			bootstrap.group(boss, work);
			bootstrap.channel(NioServerSocketChannel.class);
			bootstrap.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(512 * 1024, 1024 * 1024));
			bootstrap.childHandler(new SignallingChannelInitializer());
			channel = bootstrap.bind(Cache.signalling.getSignalingInnerPort()).sync().channel();
			log.info(">>>SignallingServer启动成功：" + channel);
			status=2;
			channel.closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
			status=3;
			log.error(">>>SignallingServer启动异常：", e);
		} finally {
			work.shutdownGracefully();
			boss.shutdownGracefully();
			if (executor != null)
			executor.shutdownNow();
			log.info(">>>SignallingServer已关闭");
			status=0;
		}
	}

	public void stop() {
		status=3;
		CachePool.KillAllUeClient();
		if (channel != null) {
			channel.close();
			channel=null;
		}
		else {
			status = 0;	
		}
	}

	public void restart() {
		stop();
	}
	
	public int getStatus() {
		return status;
	}
	
	public void destroy() {
		if(reconnectScheduledExecutor!=null) {
			reconnectScheduledExecutor.shutdown();
		}
		stop();
	}
	
	
	private ScheduledExecutorService reconnectScheduledExecutor;
	public void reconnect() {
		reconnectScheduledExecutor = new ScheduledThreadPoolExecutor(1);
		reconnectScheduledExecutor.scheduleWithFixedDelay(new TimerTask() {
			@Override
			public void run() {
				if(Cache.signalling!=null && StrKit.equals("1",Cache.signalling.getEnbaled())) {
					if (status == 0) {
						SignallingServer.getInstance().run();
					}
					else if(status == 2){
					}else {
						log.info(String.format("信令服务重连中，状态码:%s", status));
					}
				}
			}
		}, 0, 5, TimeUnit.SECONDS);
	}



}
